/*
wstatus 解释
    0-6位： 7个位置  子进程被信号中断时 信号的编号
    8-15位：表示进程退出的状态
    获取进程退出的状态  (status   & 0xFF00 ) >> 8
    获取进程中断信号   (status & 0x7f)

正常退出
WIFEXITED(wstatus)
    功能:
        判断子进程是否正常终止。如果子进程是通过调用 `exit()` 或者返回主函数而正常终止，则此宏返回一个非零值。
    说明:
        当 `WIFEXITED(wstatus)` 返回非零值时，可以使用 `WEXITSTATUS(wstatus)` 来提取子进程的退出状态，通常为子进程传递给 `exit()` 的值或主函数的返回值。
    示例:
        if (WIFEXITED(status)) {
            printf("子进程正常退出，状态码: %d\n", WEXITSTATUS(status));
        }

    方法: 子进程调用 exit() 或从主函数返回。
    代码: exit(0);

信号终止
WIFSIGNALED(wstatus)
    功能:
    	判断子进程是否因信号而终止。如果子进程因为未处理的信号（如 `SIGKILL` 或 `SIGSEGV`）而被终止，则此宏返回一个非零值。
    
    说明:
    	当 `WIFSIGNALED(wstatus)` 返回非零值时，可以使用 `WTERMSIG(wstatus)` 来提取导致子进程终止的信号编号。

    示例:
    	if (WIFSIGNALED(status)) {
        	printf("子进程被信号 %d 终止\n", WTERMSIG(status));
    	}
    方法: 父进程向子进程发送终止信号（如 SIGKILL）。
    代码: kill(pid, SIGKILL);

信号暂停
WIFSTOPPED(wstatus)
    功能:
    	判断子进程是否因信号而暂停执行。如果子进程由于接收到 `SIGSTOP` 等暂停信号而被暂停，则此宏返回一个非零值。

    说明:
    	当 `WIFSTOPPED(wstatus)` 返回非零值时，可以使用 `WSTOPSIG(wstatus)` 来提取导致子进程暂停的信号编号。

    示例:
        if (WIFSTOPPED(status)) {
            printf("子进程因信号 %d 暂停\n", WSTOPSIG(status));
        }
    方法: 父进程向子进程发送暂停信号（如 SIGSTOP）。
    代码: kill(pid, SIGSTOP);

恢复执行
    功能:
    	判断子进程是否已恢复继续执行（仅适用于支持 `WCONTINUED` 标志的系统）。如果子进程在被暂停后接收到 `SIGCONT` 信号而继续执行，则此宏返回一个非零值。

    示例:
        if (WIFCONTINUED(status)) {
            printf("子进程已恢复继续执行\n");
        }

    方法: 在子进程暂停后，父进程发送 SIGCONT 信号恢复执行。
    代码: kill(pid, SIGCONT);
*/




#include "head.h"

int main(int argc,const char *argv[])
{
    pid_t pid=0;//用于存储fork()返回的子进程ID
    int wait_read=0;//用于存储wait()返回的子进程状态

    if(-1 == (pid=fork()))
    {
        perror("fork error");
        return 0;//程序退出
    }

    //父进程
    else if(0<pid)
    {
        printf("我是父进程\n");
        sleep(1);//父进程休眠1s，模拟父进程执行一些任务
    }

    //子进程
    else if(0==pid)
    {
        printf("我是子进程\n");
        sleep(100);//子进程休眠100s，模拟子进程进行长时间的任务
        printf("子进程结束\n");
        exit(5);//子进程退出并返回状态码5
    }

    //父进程等待子进程结束
    wait(&wait_read);//调用wait()等待子程序结束，并将其退出状态码存储在wait_read中

    //判断子进程退出状态，检查是否是正常退出
    if(WIFEXITED(wait_read))
    {
        printf("子进程 正常退出 %d\n",WEXITSTATUS(wait_read));//正常退出 exit(10)
    }
    else if(WIFSIGNALED(wait_read))
    {
        printf("子进程 信号中断 %d\n",WTERMSIG(wait_read));//信号中断 kill -9 pid
    }
    else if(WIFSTOPPED(wait_read))
    {
        printf("子进程 信号暂停 %d\n",WSTOPSIG(wait_read));//信号暂停 -19 pid
    }

    //输出信息
    printf("张三\n");

    //父进程再次调用wait(),等待子进程的状态变化
    wait(&wait_read);//父进程再次等待子进程状态的变化，这通常用于获取子进程的继续执行或退出状态

    // 判断子进程是否已经恢复继续执行（如果它曾经被暂停）
    if (WIFSTOPPED(wait_read))
    {
        // 如果子进程被暂停，WIFSTOPPED 返回 true，说明子进程已恢复继续执行
        printf("子进程已恢复继续执行\n"); // 输出信息，表明子进程恢复了执行
    }

    // 父进程进入无限循环，模拟父进程的长时间运行
    while (1)
    {
        sleep(1);  // 父进程每秒钟睡眠一次，保持程序运行
    }

    return 0;  // 程序结束
}